package huanzhao.erp.util;

import cn.hutool.json.JSONUtil;
import com.github.benmanes.caffeine.cache.Cache;
import huanzhao.erp.domain.constant.CommonConstant;
import huanzhao.erp.domain.po.CacheOp;
import huanzhao.erp.domain.types.CacheTemplate;
import huanzhao.erp.domain.types.CacheType;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Objects;
import java.util.Random;
import java.util.concurrent.TimeUnit;

@Component
@Slf4j
public class CacheUtils {

    @Autowired
    private Cache<String, Object> caffeineTemplate;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    public Object getCache(String key, CacheTemplate cacheTemplate) {
        if(cacheTemplate==CacheTemplate.SINGLE){
            //从Redis中获取value，存在则直接返回
            Object res = redisTemplate.opsForValue().get(key);
            if(Objects.nonNull(res)) {
                return res;
            }
        }
        else if(cacheTemplate==CacheTemplate.MULTIPLE){
            //从Caffeine中获取value，存在则直接返回
            Object res = caffeineTemplate.getIfPresent(key);
            if(Objects.nonNull(res)) {
                return res;
            }
            //redis中查询key
            res = redisTemplate.opsForValue().get(key);
            if(Objects.nonNull(res)) {
                // 广播更新缓存的消息
                CacheOp cacheOp = new CacheOp();
                cacheOp.setType(CacheType.PUT);
                cacheOp.setKey(key);
                cacheOp.setValue(res);
                rabbitTemplate.convertAndSend(CommonConstant.FANOUT_EXCHANGE,null, JSONUtil.toJsonStr(cacheOp));
                return res;
            }
        }
        return  null;
    }

    public void delCache(String key, CacheTemplate cacheTemplate) {
        if(cacheTemplate==CacheTemplate.SINGLE){
            redisTemplate.delete(key);
        }
        else if(cacheTemplate==CacheTemplate.MULTIPLE){
            //删除Redis中的Key
            redisTemplate.delete(key);
            // 广播删除缓存的消息
            CacheOp cacheOp = new CacheOp();
            cacheOp.setType(CacheType.DELETE);
            cacheOp.setKey(key);
            rabbitTemplate.convertAndSend(CommonConstant.FANOUT_EXCHANGE,null, JSONUtil.toJsonStr(cacheOp));
        }
    }

    public void putCache(String key, Object value, long timeOut, CacheTemplate cacheTemplate) {
        if(cacheTemplate==CacheTemplate.SINGLE){
            redisTemplate.opsForValue().set(key, value, timeOut + new Random().nextInt(7), TimeUnit.SECONDS);
        }
        else if(cacheTemplate==CacheTemplate.MULTIPLE){
            //更新Redis的Key
            redisTemplate.opsForValue().set(key, value, timeOut + new Random().nextInt(7), TimeUnit.SECONDS);
            // 广播更新缓存的消息
            CacheOp cacheOp = new CacheOp();
            cacheOp.setType(CacheType.PUT);
            cacheOp.setKey(key);
            cacheOp.setValue(value);
            rabbitTemplate.convertAndSend(CommonConstant.FANOUT_EXCHANGE,null, JSONUtil.toJsonStr(cacheOp));
        }
    }
}